<template>
  <el-card shadow="hover">
    <el-button
      type="primary"
      :icon="Plus"
      @click="showTrademarkDialog({ id: 0, tmName: '', logoUrl: '' })"
      v-permission="'btn.Trademark.add'"
      >添加品牌</el-button
    >
    <el-table
      :data="trademarkList"
      border
      style="margin: 20px 0"
      v-loading="loading"
    >
      <el-table-column type="index" label="序号" width="80" align="center" />
      <el-table-column prop="tmName" label="品牌名称" />
      <!-- 
        表格要渲染存文本 ，直接prop="数据名称"
        table组件单元格中渲染图片:
          template使用默认插槽+作用域插槽 
          #default="{row,$index}" row是行，代表表格列给里面内容传的每一行数据  $index 是数据的下标
          且图片路径src需动态绑定为scope.row.prop中绑定的数据名
       -->
      <el-table-column label="品牌LOGO">
        <template #default="scope">
          <div style="display: flex; align-items: center">
            <el-image :src="scope.row.logoUrl" class="trademark__logo" />
          </div>
        </template>
      </el-table-column>
      <el-table-column label="操作" v-slot="{ row }">
        <el-button
          type="warning"
          size="small"
          :icon="Edit"
          @click="showTrademarkDialog(row)"
          title="修改品牌"
          v-permission="'btn.Trademark.update'"
        />
        <el-button
          type="danger"
          size="small"
          :icon="Delete"
          @click="showDelTrademark(row)"
          title="删除品牌"
          v-permission="'btn.Trademark.remove'"
        />
      </el-table-column>
    </el-table>
    <!-- element-plus分页器是双向数据绑定，数据直接是最新的 -->
    <el-pagination
      v-model:current-page="currentPage"
      v-model:page-size="pageSize"
      :page-sizes="[3, 6, 9, 12]"
      layout="prev, pager, next, jumper,-> ,sizes,total,"
      :total="total"
      @size-change="getTrademarkList"
      @current-change="getTrademarkList"
    />
    <!-- 
        表单验证：
          1. form中定义三个属性和定义对应响应式数据
            ref="formRef" 获取到form组件的实例对象
            :model="formData" 绑定整个表单数据（注意：定义表单数据看添加品牌的接口文档给的）
            :rules="formRules" 绑定整个表单的校验规则（注意：校验规则要和数据名字一样，数据对应数据规则）
          2. form-item中定义prop属性来接收对应数据规则
          3. v-model="formData.tmName"收集输入数据和:src="formData.logoUrl"收集图片数据
          此时只有输入表单的校验，图片没效果，需要提交整个表单去校验整个表单
          4. formRef.value.validate()
          此时可以看到图片的校验，图片添加成功，把校验提示信息清除掉
          5.formRef.value.clearValidate();
          表单校验成功，才可以拿添加的数据去发送请求       
    -->
    <el-dialog
      v-model="dialogFormVisible"
      :title="formData.id ? '修改品牌' : '添加品牌'"
    >
      <!-- 默认插槽 -->
      <el-form
        label-width="100px"
        ref="formRef"
        :model="formData"
        :rules="formRules"
      >
        <el-form-item label="品牌名称" prop="tmName">
          <el-input
            placeholder="请输入品牌名称"
            class="trademark__input"
            v-model="formData.tmName"
          />
        </el-form-item>
        <el-form-item label="品牌LOGO" prop="logoUrl">
          <!-- 
            action 上传图片服务器地址
              /admin/product/fileUpload 不对，没有服务器地址
              http://gmall-h5-api.atguigu.cn/admin/product/fileUpload 
                问题：
                  1. 跨域
                  2. 目标服务器写死了，一旦更换了环境，地址错误
              /app-dev/admin/product/fileUpload 解决跨域，但是一旦更换了环境，地址错误
              import.meta.env.VITE_API_URL 获取请求前缀

            :show-file-list="false" 是否显示文件列表（是否可以上传多张图片）
            :on-success 上传图片成功触发的回调
              得到上传图片地址
            :before-upload 上传图片之前触发的回调
              限制图片的大小和类型
            accept="image/jpeg,image/png" 能接受上传的文件类型
           -->
          <el-upload
            class="avatar-uploader"
            :action="`${BASE_URL}/admin/product/upload`"
            :show-file-list="false"
            :on-success="handleAvatarSuccess"
            :before-upload="beforeAvatarUpload"
            accept="image/jpeg,image/png"
          >
            <img
              v-if="formData.logoUrl"
              :src="formData.logoUrl"
              class="avatar"
            />
            <el-icon v-else class="avatar-uploader-icon"><Plus /></el-icon>
            <template #tip>
              <div class="el-upload__tip">
                只能上传jpg/png文件，且不超过200kb
              </div>
            </template>
          </el-upload>
        </el-form-item>
      </el-form>
      <!-- 具名插槽 -->
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="submit"> 确定 </el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "XTrademark",
};
</script>

<script lang="ts" setup>
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import { ref, onMounted, reactive } from "vue";
import {
  getTrademarkListApi,
  addTrademarkApi,
  updateTrademarkApi,
  deleteTrademarkApi,
} from "@/api/product/trademark";
import type {
  TrademarkList,
  TrademarkItem,
} from "@/api/product/model/trademarkModel";
import { ElMessage, ElMessageBox } from "element-plus";
import type { UploadProps } from "element-plus";
/****************************** 删除品牌功能 *******************************/
const showDelTrademark = async (row: TrademarkItem) => {
  ElMessageBox.confirm(`你确定要删除 ${row.tmName} 品牌吗?`, "删除品牌", {
    confirmButtonText: "确定",
    cancelButtonText: "关闭",
    type: "warning",
  })
    .then(async () => {
      await deleteTrademarkApi(row.id);
      ElMessage({
        type: "success",
        message: "删除品牌成功~",
      });
      getTrademarkList();
    })
    .catch(() => {
      // ElMessage({
      //   type: "info",
      //   message: "删除品牌失败~",
      // });
    });
};
/************************** 添加&修改品牌功能 *******************************/
// 添加/修改的对话框的显示隐藏功能
const dialogFormVisible = ref(false);
const showTrademarkDialog = (row: TrademarkItem) => {
  formData.id = row.id;
  formData.tmName = row.tmName;
  formData.logoUrl = row.logoUrl;

  // 场景：第一次表单验证不通过关闭第二次进入对话框则需要清除第一次的表单验证
  formRef.value?.clearValidate();
  dialogFormVisible.value = true;
};
// 上传图片功能
// 上传图片发送请求拼接地址
const BASE_URL = import.meta.env.VITE_API_URL; // 走代理，不同环境不同服务器
// 上传成功的回调
const handleAvatarSuccess: UploadProps["onSuccess"] = (
  response // 响应结果
  // uploadFile // 上传文件对象
) => {
  // console.log(response, uploadFile);
  // 上传图片成功：得到图片地址
  formData.logoUrl = response.data;
  // 上传图片后，就可以把校验的提示文字清除了
  formRef.value.clearValidate();
};
/*
  图片类型
    image/jpeg image/gif  image/png
    video/mp4
    application/json
    ...
  图片大小 
    bit  位
    byte 字节  1字节 = 8位
    kb 千 1千 = 1024字节
    mb
    gb
    tb
*/
// 上传文件之前的回调
// 限制图片的类型和图片大小
// rawFile 代表上传图片文件数据
const beforeAvatarUpload: UploadProps["beforeUpload"] = (rawFile) => {
  const filesType = ["image/jpeg", "image/png"];
  if (!filesType.includes(rawFile.type)) {
    ElMessage.error("上传的图片只能是jpg或png格式!");
    return false;
  } else if (rawFile.size / 1024 > 200) {
    // 单位字节byte
    ElMessage.error("图片大小不能超过200kb!");
    return false;
  }
  return true;
};
// 表单校验功能
const formRef = ref(); // ref获取表单实例对象
// 整个表单的数据（看添加品牌的接口文档）
const formData = reactive({
  id: 0,
  tmName: "",
  logoUrl: "",
});
// 整个表单的校验规则(要和数据名字一样，数据对应数据规则)
const formRules = reactive({
  tmName: [
    { required: true, message: "请输入品牌名称", trigger: "blur" },
    { min: 2, max: 10, message: "品牌名称长度为2-10", trigger: "blur" },
  ],
  logoUrl: [{ required: true, message: "请选择品牌LOGO" }],
});
// 提交表单
const submit = async () => {
  // 校验整个表单
  await formRef.value.validate();
  // 校验通过，才可以拿添加的数据请求
  const { id, tmName, logoUrl } = formData;
  if (id) {
    // 修改
    await updateTrademarkApi(formData);
    ElMessage.success("修改品牌成功~");
  } else {
    // 添加
    await addTrademarkApi(tmName, logoUrl);
    ElMessage.success("添加品牌成功~");
  }
  // 关闭对话框
  dialogFormVisible.value = false;
  // 重新获取分页列表
  getTrademarkList();
};
/*************************** 分页展示功能 *********************************/
// 分页器数据
const currentPage = ref(1);
const pageSize = ref(3);
const total = ref(0);
const loading = ref(false);
// const handleSizeChange = () => {
//   getTrademarkList();
// };
// const handleCurrentChange = () => {
//   getTrademarkList();
// };

// 分页列表数据
const trademarkList = ref<TrademarkList>([]);
// 发送请求获取分页列表
const getTrademarkList = async () => {
  loading.value = true;
  const res = await getTrademarkListApi(currentPage.value, pageSize.value);
  trademarkList.value = res.records;
  total.value = res.total;
  loading.value = false;
};
// onMounted(() => {
//   getTrademarkList();
// });
// 简写  函数里面调用函数
onMounted(getTrademarkList);
</script>

<style scoped lang="scss">
.trademark__logo {
  width: 100px;
  height: 60px;
}
.trademark__input {
  width: 450px;
}
.avatar-uploader {
  .avatar {
    width: 178px;
    height: 178px;
    display: block;
  }
  // 深度样式（简写）父组件修改子组件样式
  :deep() {
    .el-upload {
      border: 1px dashed var(--el-border-color);
      border-radius: 6px;
      cursor: pointer;
      position: relative;
      overflow: hidden;
      transition: var(--el-transition-duration-fast);
    }
    .el-upload:hover {
      border-color: var(--el-color-primary);
    }
    .el-icon.avatar-uploader-icon {
      font-size: 28px;
      color: #8c939d;
      width: 178px;
      height: 178px;
      text-align: center;
    }
  }
}
</style>
